'''
Created on Jul 30, 2013

@author: Cihat Basol
'''


import time

from dexen.common import db
from dexen.server.backend import task_manager as tm


class JobManager(object):
    RUNNING = "JOB_RUNNING"
    STOPPED = "JOB_STOPPED"

    def __init__(self, user_name, job_name, db_client):
        self.user_name = user_name
        self.job_name = job_name
        self.creation_time = time.time()
        self.start_time = None
        self.stop_time = None
        self.state = JobManager.STOPPED
        self.event_task_mgr = tm.EventTaskManager()
        self.dataflow_task_mgr = tm.DataFlowTaskManager(
                db.JobDataManager(db_client, user_name, job_name))

    @property
    def is_running(self):
        return self.state == JobManager.RUNNING

    def run(self):
        self.state = JobManager.RUNNING
        self.start_time = time.time()
        self.event_task_mgr.on_job_start()

    def stop(self):
        self.state = JobManager.STOPPED
        self.stop_time = time.time()
        self.event_task_mgr.on_job_stop()

    def register_task(self, task):
        if task.is_event_task:
            self.event_task_mgr.register_task(task)
        else:
            self.dataflow_task_mgr.register_task(task)

    def deregister_task(self, task_name):
        self.event_task_mgr.deregister_task(task_name)
        self.dataflow_task_mgr.deregister_task(task_name)

    def get_task(self):
        task = self.event_task_mgr.get_task()
        if not task:
            task = self.dataflow_task_mgr.get_task()
        return task

    def undo_get_task(self, task):
        if task.is_event_task:
            self.event_task_mgr.undo_get_task(task)
        else:
            self.dataflow_task_mgr.undo_get_task(task)

    def on_execution_scheduled(self, execution):
        if execution.task.is_event_task:
            self.event_task_mgr.on_execution_scheduled(execution)
        else:
            self.dataflow_task_mgr.on_execution_scheduled(execution)

    def on_execution_completed(self, scheduled_execution, execution_result):
        if execution_result.task.is_event_task:
            self.event_task_mgr.on_execution_completed(scheduled_execution,
                                                       execution_result)
        # The even task might have generated data which is used by DataFlow task.
        # Therefore, we still handle the event task in dataflow task manager.
        self.dataflow_task_mgr.on_execution_completed(scheduled_execution,
                                                      execution_result)

    def on_execution_failed(self, execution):
        if execution.task.is_event_task:
            self.event_task_mgr.on_execution_failed(execution)
        # The even task might have generated data which is used by DataFlow task.
        # Therefore, we still handle the event task in dataflow task manager.
        self.dataflow_task_mgr.on_execution_failed(execution)

    def json_info(self):
        info = {
            "job_name" : self.job_name,
            "creation_time" : self.creation_time,
            "start_time" : self.start_time,
            "stop_time" : self.stop_time
        }
        if self.is_running:
            info["status"] = "RUNNING"
        else:
            info["status"] = "STOPPED"
        
        info["event_tasks"] = self.event_task_mgr.json_info()
        return info

